package br.usp.pcs.basys2.peripheral;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;

import br.usp.pcs.basys2.BasysProcess;
import br.usp.pcs.basys2.info.PeripheralInfo;

public class Peripheral {
	private Queue<BasysProcess> processesQueue = new LinkedList<BasysProcess>();
	private BasysProcess accessingProcess = null;
	private Set<PeripheralManagerListener> listeners = new HashSet<PeripheralManagerListener>();
	private PeripheralInfo info;
	
	public Integer getAccessTime() {
		return info.getAccessTime();
	}

	public String getName() {
		return info.getName();
	}

	public Peripheral(PeripheralInfo info) {
		super();
		this.info = info;
	}

	public boolean add(PeripheralManagerListener e) {
		return listeners.add(e);
	}
	
	public void requestAcess(BasysProcess jobprocess) {
		if (peripheralIsFree()) {
			startAccess(jobprocess);
		}
		else {
			processesQueue.add(jobprocess);
		}
	}
	
	private void startAccess(BasysProcess basysProcess) {
		accessingProcess = basysProcess;
		
		for (PeripheralManagerListener listener : listeners) {
			listener.onProcesStartedAccessingPeripheral(basysProcess, this.getName());
		}
	}
	
	public void endAccess(){
		for (PeripheralManagerListener listener : listeners) {
			listener.onProcesStopedAccessingPeripheral(accessingProcess, this.getName());
		}
		if (!processesQueue.isEmpty()){
			startAccess(processesQueue.poll());
		} else {
			accessingProcess = null;
		}
	}

	public boolean peripheralIsFree(){
		return accessingProcess == null;
	}

	public BasysProcess getAccessingProcess() {
		return accessingProcess;
	}

}
